R_Date_time_Handle_R Notebook

1、取出当前日期

Sys.Date()
[1] "2017-07-08"

2、在R中日期实际是double类型,是从1970年1月1日以来的天数

typeof(Sys.Date())
# [1] "double"

3、转换为日期

as.Date()可以将一个字符串转换为日期值,默认格式是yyyy-mm-dd

as.Date("2007-02-01")   #得到"2007-02-01",显示为字符串,但实际是用double存储的
as.double(as.Date("1970-01-01"))  #结果为0,是从1970年1月1日以来的天数。

# 可以把定制的日期字符串转换为日期型
as.Date("2007年2月1日", "%Y年%m月%d日") 
# [1] "2007-02-01"

x<-as.Date("1970-01-01")   
unclass(x)   
# [1] 0  

unclass(as.Date("1970-02-01")) #19700201代表第31天  
# [1] 31  
# unclass可以将日期变成以天来计数,
# 比如1970-02-01输出的31,就代表着距离1970-01-01有31天。

格式 意义 %Y 年份,以四位数字表示,2007 %m 月份,以数字形式表示,从01到12 %d 月份中当的天数,从01到31 %b 月份,缩写,Feb %B 月份,完整的月份名,指英文,February %y 年份,以二位数字表示,07

4、把日期值输出为字符串

today <- Sys.Date()
format(today, "%Y年%m月%d日")
# [1] "2014年10月29日"

5、计算日期差

由于日期内部是用double存储的天数,所以是可以相减的。

today <- Sys.Date()
gtd <- as.Date("2011-07-01")   
today - gtd
# Time difference of 1216 days  

difftime()函数可以计算相关的秒数、分钟数、小时数、天数、周数

difftime(today, gtd, units="weeks")  
#还可以是“secs”, “mins”, “hours”, “days”
# Time difference of 173.7143 weeks

6. 日期型数据

在R中自带的日期形式为:as.Date();以数值形式存储;

对于规则的格式,则不需要用format指定格式; 如果输入的格式不规则,可以通过format指定的格式读入;

标准格式: 年-月-日或者年/月/日; 如果不是以上二种格式,则会提供错误;

as.Date('23-2013-1')
# 错误于charTo按照Date(x) : 字符串的格式不够标准明确

as.Date('23-2013-1',format='%d-%Y-%m')
# [1] "2013-01-23"

格式 意义 %Y 年份,以四位数字表示,2007 %m 月份,以数字形式表示,从01到12 %d 月份中当的天数,从01到31 %b 月份,缩写,Feb %B 月份,完整的月份名,指英文,February %y 年份,以二位数字表示,07

其它日期相关函数

weekdays() 取日期对象所处的周几; months() 取日期对象的月份; quarters() 取日期对象的季度;

7. POSIX类

The POSIXct class stores date/time values as the number of seconds since January 1, 1970, while the POSIXlt class stores them as a list with elements for second, minute, hour, day, month, and year, among others.

POSIXct 是以1970年1月1号开始的以秒进行存储,如果是负数,则是1970年以前;正数则是1970年以后。

POSIXlt 是以列表的形式存储:年、月、日、时、分、秒;作用是打散时间,把时间分成年、月、日、时、分、秒,并进行存储。

today <- Sys.time()  
unclass(as.POSIXlt(today))  
# $sec
# [1] 49.00171
# 
# $min
# [1] 15
# 
# $hour
# [1] 0
# 
# $mday
# [1] 4
# 
# $mon
# [1] 6
# 
# $year
# [1] 117
# 
# $wday
# [1] 2
# 
# $yday
# [1] 184
# 
# $isdst
# [1] 0
# 
# $zone
# [1] "CST"
# 
# $gmtoff
# [1] 28800
# 
# attr(,"tzone")
# [1] ""    "CST" "CDT"

mydate = as.POSIXlt('2005-4-19 7:01:00')
names(mydate)

默认情况下,日期之前是以/或者-进行分隔,而时间则以:进行分隔;

输入的标准格式为:日期 时间(日期与时间中间有空隔隔开)

时间的标准格式为:时:分 或者 时:分:秒;

如果输入的格式不是标准格式,则同样需要使用strptime函数,利用format来进行指定;

## 生成案例数据
Dates <- c("2009-09-28","2010-01-15")
Times <- c( "23:12:55", "10:34:02")
charvec <- timeDate(paste(Dates, Times))
timeDate(charvec)

#取系统的时间
Sys.timeDate()

#一个月的第一天
timeFirstDayInMonth()

#一个月的最后一天
timeLastDayInMonth()

#一周当中第几天
dayOfWeek()

#一年当中的第几天
dayOfYear()

Sys.Date()
# returns today's date. 

date()
# returns the current date and time.

# print today's date
today <-Sys.Date()
format(today, format="%B %d %Y")
# "June 20 2007"

now_ct <- Sys.time()  
now_ct  
# [1] "2015-10-29 21:36:41 CST"  
class(now_ct)  
# [1] "POSIXct" "POSIXt"   

date <- as.Date(now_ct)  
date  
# [1] "2015-10-29" 

# convert date info in format 'mm/dd/yyyy'
strDates <- c("01/05/1965", "08/16/1975")
dates <- as.Date(strDates, "%m/%d/%Y") 

# convert dates to character data
strDates <- as.character(dates)

as.Date('1915-6-16')
# [1] "1915-06-16"

as.Date('1990/02/17')
# [1] "1990-02-17"

as.Date('1/15/2001',format='%m/%d/%Y')
# [1] "2001-01-15"

as.Date('April 26, 2001',format='%B %d, %Y')
# [1] "2001-04-26"

as.Date('22JUN01',format='%d%b%y')   # %y is system-specific; use with caution
# [1] "2001-06-22"

bdays = c(tukey=as.Date('1915-06-16'),fisher=as.Date('1890-02-17'),
           cramer=as.Date('1893-09-25'), kendall=as.Date('1907-09-06'))
weekdays(bdays)
      # tukey      fisher      cramer     kendall
# "Wednesday"    "Monday"    "Monday"    "Friday"

dtimes = c("2002-06-09 12:45:40","2003-01-29 09:30:40",
          "2002-09-04 16:45:40","2002-11-13 20:00:40",
          "2002-07-07 17:30:40")
dtparts = t(as.data.frame(strsplit(dtimes,' ')))
row.names(dtparts) = NULL
thetimes = chron(dates=dtparts[,1],times=dtparts[,2],
          format=c('y-m-d','h:m:s'))
thetimes
# [1] (02-06-09 12:45:40) (03-01-29 09:30:40) (02-09-04 16:45:40)
# [4] (02-11-13 20:00:40) (02-07-07 17:30:40)


dts = c("2005-10-21 18:47:22",
        "2005-12-24 16:39:58",
        "2005-10-28 07:30:05 PDT")
as.POSIXlt(dts)
# [1] "2005-10-21 18:47:22" "2005-12-24 16:39:58" 
# [3] "2005-10-28 07:30:05"


dts = c(1127056501,1104295502,1129233601,1113547501,
        1119826801,1132519502,1125298801,1113289201)
mydates = dts
class(mydates) = c('POSIXt','POSIXct')
mydates
# [1] "2005-09-18 08:15:01 PDT" "2004-12-28 20:45:02 PST"
# [3] "2005-10-13 13:00:01 PDT" "2005-04-14 23:45:01 PDT"
# [5] "2005-06-26 16:00:01 PDT" "2005-11-20 12:45:02 PST"
# [7] "2005-08-29 00:00:01 PDT" "2005-04-12 00:00:01 PDT"

mydate = strptime('16/Oct/2005:07:51:00',format='%d/%b/%Y:%H:%M:%S')
# [1] "2005-10-16 07:51:00"

ISOdate(2005,10,21,18,47,22,tz="PDT")
# [1] "2005-10-21 18:47:22 PDT"

thedate = ISOdate(2005,10,21,18,47,22,tz="PDT")
format(thedate,'%A, %B %d, %Y %H:%M:%S')
# [1] "Friday, October 21, 2005 18:47:22"

mydate = as.POSIXlt('2005-4-19 7:01:00')
names(mydate)
# [1] "sec"   "min"   "hour"  "mday"  "mon"   "year"  
# [7] "wday"  "yday"  "isdst"

mydate$mday
# [1] 19

POSIXct 格式

主要特点:以秒进行存储。

today<-Sys.time()  
today  
# [1] "2016-06-06 20:42:22 CST"  

unclass(as.POSIXct(today))  
# [1] 1465216942  
# 解读:比如今天,unclass之后,
# 代表今天2016-06-06距离1970-01-01为1465216942秒。
#GMT代表时区,德意志时间,CST也代表时区

8.如何在循环、函数中,输出实时时间消耗

t1 = Sys.time()  
for (i in 1:5){  
a=a+1  
b=a*a  
print(difftime(Sys.time(), t1, units = 'sec'))  
}  

9. How to change the locale of R in RStudio?

The R console is in my native language, how can I set R to English?

  1. Go into R installation directory, i.e. C:Files
  2. From there go into the subfolder etc/

  3. Open with a text editor (i.e. Notepad) the file Rconsole

  4. Look into the file for the line language =

  5. Replace such line with language = en

  6. Save and close the Rconsole file, then run Rgui again, and the interface will be in English

R version 3.1.3

input string 1 is invalid in this locale

The issue is that you have a French/Chinese etc locale, which uses different month and day names and abbreviations. You can change to the English locale by running:

Sys.setlocale('LC_ALL','English');
[1] "LC_COLLATE=English_United States.1252;LC_CTYPE=English_United States.1252;LC_MONETARY=English_United States.1252;LC_NUMERIC=C;LC_TIME=English_United States.1252"

10. How to update R in RStudio using installr package for Windows


## How to update R in RStudio using installr package (for Windows)
## paste this into the console and run the commands
## "The updateR() command performs the following: finding the latest R version, downloading it, running the installer, deleting the installation file, copy and updating old packages to the new R installation."
## more info here: https://cran.r-project.org/web/packages/installr/index.html

# The installr package seems like a great solution but unfortunately is only for Windows.

# installing/loading the package,load /install+load installr  
if(!require(installr)){ 
  install.packages("installr"); 
  require(installr)} 

# using the installr package, install, move, update.package, quit R.
## Watch for small pop up windows. There will be many questions and they don't always pop to the front. 
## Note: It warns that it might work better in Rgui but I did it in Rstudio and it worked just fine. 
# this will start the updating process of your R installation.  
# It will check for newer versions, and if one is available, will guide you through the decisions you'd need to make.
updateR()

11. R sessionInfo, version, packageStatus

# session, version, packageStatus
sessionInfo()
version

# get r version
R.version.string

packageStatus()
LS0tDQp0aXRsZTogIlJfRGF0ZV90aW1lX0hhbmRsZV9SIE5vdGVib29rIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazogDQogICAgdG9jOiB5ZXMNCi0tLQ0KDQojIFJfRGF0ZV90aW1lX0hhbmRsZV9SIE5vdGVib29rDQoNCiMjIDHjgIHlj5blh7rlvZPliY3ml6XmnJ8NCmBgYHtyfQ0KU3lzLkRhdGUoKQ0KIyBbMV0gIjIwMTQtMTAtMjkiDQpkYXRlKCkgICPms6jmhI/vvJrov5nnp43mlrnms5Xov5Tlm57nmoTmmK/lrZfnrKbkuLLnsbvlnosNCiMgWzFdICJXZWQgT2N0IDI5IDIwOjM2OjA3IDIwMTQiDQpgYGANCg0KIyMgMuOAgeWcqFLkuK3ml6XmnJ/lrp7pmYXmmK9kb3VibGXnsbvlnovvvIzmmK/ku44xOTcw5bm0MeaciDHml6Xku6XmnaXnmoTlpKnmlbANCmBgYHtyfQ0KdHlwZW9mKFN5cy5EYXRlKCkpDQojIFsxXSAiZG91YmxlIg0KYGBgDQoNCiMjIDPjgIHovazmjaLkuLrml6XmnJ8NCg0K55SoYGFzLkRhdGUoKWDlj6/ku6XlsIbkuIDkuKrlrZfnrKbkuLLovazmjaLkuLrml6XmnJ/lgLzvvIzpu5jorqTmoLzlvI/mmK9geXl5eS1tbS1kZGDjgIINCmBgYHtyfQ0KYXMuRGF0ZSgiMjAwNy0wMi0wMSIpICAgI+W+l+WIsCIyMDA3LTAyLTAxIu+8jOaYvuekuuS4uuWtl+espuS4su+8jOS9huWunumZheaYr+eUqGRvdWJsZeWtmOWCqOeahA0KYXMuZG91YmxlKGFzLkRhdGUoIjE5NzAtMDEtMDEiKSkgICPnu5PmnpzkuLow77yM5piv5LuOMTk3MOW5tDHmnIgx5pel5Lul5p2l55qE5aSp5pWw44CCDQoNCiMg5Y+v5Lul5oqK5a6a5Yi255qE5pel5pyf5a2X56ym5Liy6L2s5o2i5Li65pel5pyf5Z6LDQphcy5EYXRlKCIyMDA35bm0MuaciDHml6UiLCAiJVnlubQlbeaciCVk5pelIikgDQojIFsxXSAiMjAwNy0wMi0wMSINCg0KeDwtYXMuRGF0ZSgiMTk3MC0wMS0wMSIpICAgDQp1bmNsYXNzKHgpICAgDQojIFsxXSAwICANCg0KdW5jbGFzcyhhcy5EYXRlKCIxOTcwLTAyLTAxIikpICMxOTcwMDIwMeS7o+ihqOesrDMx5aSpICANCiMgWzFdIDMxICANCiMgdW5jbGFzc+WPr+S7peWwhuaXpeacn+WPmOaIkOS7peWkqeadpeiuoeaVsO+8jA0KIyDmr5TlpoIxOTcwLTAyLTAx6L6T5Ye655qEMzHvvIzlsLHku6PooajnnYDot53nprsxOTcwLTAxLTAx5pyJMzHlpKnjgIINCg0KDQpgYGANCg0K5qC85byPICDmhI/kuYkNCiVZICDlubTku73vvIzku6Xlm5vkvY3mlbDlrZfooajnpLrvvIwyMDA3DQolbSAg5pyI5Lu977yM5Lul5pWw5a2X5b2i5byP6KGo56S677yM5LuOMDHliLAxMg0KJWQgIOaciOS7veS4reW9k+eahOWkqeaVsO+8jOS7jjAx5YiwMzENCiViICDmnIjku73vvIznvKnlhpnvvIxGZWINCiVCICDmnIjku73vvIzlrozmlbTnmoTmnIjku73lkI3vvIzmjIfoi7HmlofvvIxGZWJydWFyeQ0KJXkgIOW5tOS7ve+8jOS7peS6jOS9jeaVsOWtl+ihqOekuu+8jDA3DQoNCiMjIDTjgIHmiorml6XmnJ/lgLzovpPlh7rkuLrlrZfnrKbkuLINCmBgYHtyfQ0KdG9kYXkgPC0gU3lzLkRhdGUoKQ0KZm9ybWF0KHRvZGF5LCAiJVnlubQlbeaciCVk5pelIikNCiMgWzFdICIyMDE05bm0MTDmnIgyOeaXpSINCmBgYA0KDQojIyA144CB6K6h566X5pel5pyf5beuDQoNCueUseS6juaXpeacn+WGhemDqOaYr+eUqGRvdWJsZeWtmOWCqOeahOWkqeaVsO+8jOaJgOS7peaYr+WPr+S7peebuOWHj+eahOOAgg0KYGBge3J9DQp0b2RheSA8LSBTeXMuRGF0ZSgpDQpndGQgPC0gYXMuRGF0ZSgiMjAxMS0wNy0wMSIpICAgDQp0b2RheSAtIGd0ZA0KIyBUaW1lIGRpZmZlcmVuY2Ugb2YgMTIxNiBkYXlzICANCmBgYA0KDQrnlKhgZGlmZnRpbWUoKWDlh73mlbDlj6/ku6XorqHnrpfnm7jlhbPnmoTnp5LmlbDjgIHliIbpkp/mlbDjgIHlsI/ml7bmlbDjgIHlpKnmlbDjgIHlkajmlbANCmBgYHtyfQ0KZGlmZnRpbWUodG9kYXksIGd0ZCwgdW5pdHM9IndlZWtzIikgIA0KI+i/mOWPr+S7peaYr+KAnHNlY3PigJ0sIOKAnG1pbnPigJ0sIOKAnGhvdXJz4oCdLCDigJxkYXlz4oCdDQojIFRpbWUgZGlmZmVyZW5jZSBvZiAxNzMuNzE0MyB3ZWVrcw0KYGBgDQoNCiMjIDYuIOaXpeacn+Wei+aVsOaNrg0KDQrlnKhS5Lit6Ieq5bim55qE5pel5pyf5b2i5byP5Li677yaYXMuRGF0ZSgpO+S7peaVsOWAvOW9ouW8j+WtmOWCqO+8mw0KDQrlr7nkuo7op4TliJnnmoTmoLzlvI/vvIzliJnkuI3pnIDopoHnlKhmb3JtYXTmjIflrprmoLzlvI/vvJsNCuWmguaenOi+k+WFpeeahOagvOW8j+S4jeinhOWIme+8jOWPr+S7pemAmui/h2Zvcm1hdOaMh+WumueahOagvOW8j+ivu+WFpe+8mw0KDQrmoIflh4bmoLzlvI/vvJoNCuW5tC3mnIgt5pel5oiW6ICF5bm0L+aciC/ml6XvvJsNCuWmguaenOS4jeaYr+S7peS4iuS6jOenjeagvOW8j++8jOWImeS8muaPkOS+m+mUmeivr++8mw0KDQpgYGB7cn0NCmFzLkRhdGUoJzIzLTIwMTMtMScpDQojIOmUmeivr+S6jmNoYXJUb+aMieeFp0RhdGUoeCkgOiDlrZfnrKbkuLLnmoTmoLzlvI/kuI3lpJ/moIflh4bmmI7noa4NCg0KYXMuRGF0ZSgnMjMtMjAxMy0xJyxmb3JtYXQ9JyVkLSVZLSVtJykNCiMgWzFdICIyMDEzLTAxLTIzIg0KYGBgDQoNCuagvOW8jyAg5oSP5LmJDQolWSAg5bm05Lu977yM5Lul5Zub5L2N5pWw5a2X6KGo56S677yMMjAwNw0KJW0gIOaciOS7ve+8jOS7peaVsOWtl+W9ouW8j+ihqOekuu+8jOS7jjAx5YiwMTINCiVkICDmnIjku73kuK3lvZPnmoTlpKnmlbDvvIzku44wMeWIsDMxDQolYiAg5pyI5Lu977yM57yp5YaZ77yMRmViDQolQiAg5pyI5Lu977yM5a6M5pW055qE5pyI5Lu95ZCN77yM5oyH6Iux5paH77yMRmVicnVhcnkNCiV5ICDlubTku73vvIzku6XkuozkvY3mlbDlrZfooajnpLrvvIwwNw0KDQojIyDlhbblroPml6XmnJ/nm7jlhbPlh73mlbANCg0KYHdlZWtkYXlzKClgIOWPluaXpeacn+WvueixoeaJgOWkhOeahOWRqOWHoO+8mw0KYG1vbnRocygpYCDlj5bml6XmnJ/lr7nosaHnmoTmnIjku73vvJsNCmBxdWFydGVycygpYCDlj5bml6XmnJ/lr7nosaHnmoTlraPluqbvvJsNCg0KIyMgNy4gUE9TSVjnsbsNCg0KVGhlIFBPU0lYY3QgY2xhc3Mgc3RvcmVzIGRhdGUvdGltZSB2YWx1ZXMgYXMgdGhlIG51bWJlciBvZiBzZWNvbmRzIHNpbmNlIEphbnVhcnkgMSwgMTk3MCwgd2hpbGUgdGhlIFBPU0lYbHQgY2xhc3Mgc3RvcmVzIHRoZW0gYXMgYSBsaXN0IHdpdGggZWxlbWVudHMgZm9yIHNlY29uZCwgbWludXRlLCBob3VyLCBkYXksIG1vbnRoLCBhbmQgeWVhciwgYW1vbmcgb3RoZXJzLg0KDQpQT1NJWGN0IOaYr+S7pTE5NzDlubQx5pyIMeWPt+W8gOWni+eahOS7peenkui/m+ihjOWtmOWCqO+8jOWmguaenOaYr+i0n+aVsO+8jOWImeaYrzE5NzDlubTku6XliY3vvJvmraPmlbDliJnmmK8xOTcw5bm05Lul5ZCO44CCDQoNClBPU0lYbHQg5piv5Lul5YiX6KGo55qE5b2i5byP5a2Y5YKo77ya5bm044CB5pyI44CB5pel44CB5pe244CB5YiG44CB56eS77yb5L2c55So5piv5omT5pWj5pe26Ze077yM5oqK5pe26Ze05YiG5oiQ5bm044CB5pyI44CB5pel44CB5pe244CB5YiG44CB56eS77yM5bm26L+b6KGM5a2Y5YKo44CCDQoNCmBgYHtyfQ0KdG9kYXkgPC0gU3lzLnRpbWUoKSAgDQp1bmNsYXNzKGFzLlBPU0lYbHQodG9kYXkpKSAgDQojICRzZWMNCiMgWzFdIDQ5LjAwMTcxDQojIA0KIyAkbWluDQojIFsxXSAxNQ0KIyANCiMgJGhvdXINCiMgWzFdIDANCiMgDQojICRtZGF5DQojIFsxXSA0DQojIA0KIyAkbW9uDQojIFsxXSA2DQojIA0KIyAkeWVhcg0KIyBbMV0gMTE3DQojIA0KIyAkd2RheQ0KIyBbMV0gMg0KIyANCiMgJHlkYXkNCiMgWzFdIDE4NA0KIyANCiMgJGlzZHN0DQojIFsxXSAwDQojIA0KIyAkem9uZQ0KIyBbMV0gIkNTVCINCiMgDQojICRnbXRvZmYNCiMgWzFdIDI4ODAwDQojIA0KIyBhdHRyKCwidHpvbmUiKQ0KIyBbMV0gIiIgICAgIkNTVCIgIkNEVCINCg0KbXlkYXRlID0gYXMuUE9TSVhsdCgnMjAwNS00LTE5IDc6MDE6MDAnKQ0KbmFtZXMobXlkYXRlKQ0KDQpgYGANCg0KDQrpu5jorqTmg4XlhrXkuIvvvIzml6XmnJ/kuYvliY3mmK/ku6Uv5oiW6ICFLei/m+ihjOWIhumalO+8jOiAjOaXtumXtOWImeS7pe+8mui/m+ihjOWIhumalO+8mw0KDQrovpPlhaXnmoTmoIflh4bmoLzlvI/kuLrvvJrml6XmnJ8g5pe26Ze077yI5pel5pyf5LiO5pe26Ze05Lit6Ze05pyJ56m66ZqU6ZqU5byA77yJDQoNCuaXtumXtOeahOagh+WHhuagvOW8j+S4uu+8muaXtjrliIYg5oiW6ICFIOaXtjrliIY656eS77ybDQoNCuWmguaenOi+k+WFpeeahOagvOW8j+S4jeaYr+agh+WHhuagvOW8j++8jOWImeWQjOagt+mcgOimgeS9v+eUqHN0cnB0aW1l5Ye95pWw77yM5Yip55SoZm9ybWF05p2l6L+b6KGM5oyH5a6a77ybDQoNCmBgYHtyfQ0KIyMg55Sf5oiQ5qGI5L6L5pWw5o2uDQpEYXRlcyA8LSBjKCIyMDA5LTA5LTI4IiwiMjAxMC0wMS0xNSIpDQpUaW1lcyA8LSBjKCAiMjM6MTI6NTUiLCAiMTA6MzQ6MDIiKQ0KY2hhcnZlYyA8LSB0aW1lRGF0ZShwYXN0ZShEYXRlcywgVGltZXMpKQ0KdGltZURhdGUoY2hhcnZlYykNCg0KI+WPluezu+e7n+eahOaXtumXtA0KU3lzLnRpbWVEYXRlKCkNCg0KI+S4gOS4quaciOeahOesrOS4gOWkqQ0KdGltZUZpcnN0RGF5SW5Nb250aCgpDQoNCiPkuIDkuKrmnIjnmoTmnIDlkI7kuIDlpKkNCnRpbWVMYXN0RGF5SW5Nb250aCgpDQoNCiPkuIDlkajlvZPkuK3nrKzlh6DlpKkNCmRheU9mV2VlaygpDQoNCiPkuIDlubTlvZPkuK3nmoTnrKzlh6DlpKkNCmRheU9mWWVhcigpDQoNClN5cy5EYXRlKCkNCiMgcmV0dXJucyB0b2RheSdzIGRhdGUuIA0KDQpkYXRlKCkNCiMgcmV0dXJucyB0aGUgY3VycmVudCBkYXRlIGFuZCB0aW1lLg0KDQojIHByaW50IHRvZGF5J3MgZGF0ZQ0KdG9kYXkgPC1TeXMuRGF0ZSgpDQpmb3JtYXQodG9kYXksIGZvcm1hdD0iJUIgJWQgJVkiKQ0KIyAiSnVuZSAyMCAyMDA3Ig0KDQpub3dfY3QgPC0gU3lzLnRpbWUoKSAgDQpub3dfY3QgIA0KIyBbMV0gIjIwMTUtMTAtMjkgMjE6MzY6NDEgQ1NUIiAgDQpjbGFzcyhub3dfY3QpICANCiMgWzFdICJQT1NJWGN0IiAiUE9TSVh0IiAgIA0KDQpkYXRlIDwtIGFzLkRhdGUobm93X2N0KSAgDQpkYXRlICANCiMgWzFdICIyMDE1LTEwLTI5IiANCg0KIyBjb252ZXJ0IGRhdGUgaW5mbyBpbiBmb3JtYXQgJ21tL2RkL3l5eXknDQpzdHJEYXRlcyA8LSBjKCIwMS8wNS8xOTY1IiwgIjA4LzE2LzE5NzUiKQ0KZGF0ZXMgPC0gYXMuRGF0ZShzdHJEYXRlcywgIiVtLyVkLyVZIikgDQoNCiMgY29udmVydCBkYXRlcyB0byBjaGFyYWN0ZXIgZGF0YQ0Kc3RyRGF0ZXMgPC0gYXMuY2hhcmFjdGVyKGRhdGVzKQ0KDQphcy5EYXRlKCcxOTE1LTYtMTYnKQ0KIyBbMV0gIjE5MTUtMDYtMTYiDQoNCmFzLkRhdGUoJzE5OTAvMDIvMTcnKQ0KIyBbMV0gIjE5OTAtMDItMTciDQoNCmFzLkRhdGUoJzEvMTUvMjAwMScsZm9ybWF0PSclbS8lZC8lWScpDQojIFsxXSAiMjAwMS0wMS0xNSINCg0KYXMuRGF0ZSgnQXByaWwgMjYsIDIwMDEnLGZvcm1hdD0nJUIgJWQsICVZJykNCiMgWzFdICIyMDAxLTA0LTI2Ig0KDQphcy5EYXRlKCcyMkpVTjAxJyxmb3JtYXQ9JyVkJWIleScpICAgIyAleSBpcyBzeXN0ZW0tc3BlY2lmaWM7IHVzZSB3aXRoIGNhdXRpb24NCiMgWzFdICIyMDAxLTA2LTIyIg0KDQpiZGF5cyA9IGModHVrZXk9YXMuRGF0ZSgnMTkxNS0wNi0xNicpLGZpc2hlcj1hcy5EYXRlKCcxODkwLTAyLTE3JyksDQogICAgICAgICAgIGNyYW1lcj1hcy5EYXRlKCcxODkzLTA5LTI1JyksIGtlbmRhbGw9YXMuRGF0ZSgnMTkwNy0wOS0wNicpKQ0Kd2Vla2RheXMoYmRheXMpDQogICAgICAjIHR1a2V5ICAgICAgZmlzaGVyICAgICAgY3JhbWVyICAgICBrZW5kYWxsDQojICJXZWRuZXNkYXkiICAgICJNb25kYXkiICAgICJNb25kYXkiICAgICJGcmlkYXkiDQoNCmR0aW1lcyA9IGMoIjIwMDItMDYtMDkgMTI6NDU6NDAiLCIyMDAzLTAxLTI5IDA5OjMwOjQwIiwNCiAgICAgICAgICAiMjAwMi0wOS0wNCAxNjo0NTo0MCIsIjIwMDItMTEtMTMgMjA6MDA6NDAiLA0KICAgICAgICAgICIyMDAyLTA3LTA3IDE3OjMwOjQwIikNCmR0cGFydHMgPSB0KGFzLmRhdGEuZnJhbWUoc3Ryc3BsaXQoZHRpbWVzLCcgJykpKQ0Kcm93Lm5hbWVzKGR0cGFydHMpID0gTlVMTA0KdGhldGltZXMgPSBjaHJvbihkYXRlcz1kdHBhcnRzWywxXSx0aW1lcz1kdHBhcnRzWywyXSwNCiAgICAgICAgICBmb3JtYXQ9YygneS1tLWQnLCdoOm06cycpKQ0KdGhldGltZXMNCiMgWzFdICgwMi0wNi0wOSAxMjo0NTo0MCkgKDAzLTAxLTI5IDA5OjMwOjQwKSAoMDItMDktMDQgMTY6NDU6NDApDQojIFs0XSAoMDItMTEtMTMgMjA6MDA6NDApICgwMi0wNy0wNyAxNzozMDo0MCkNCg0KDQpkdHMgPSBjKCIyMDA1LTEwLTIxIDE4OjQ3OjIyIiwNCiAgICAgICAgIjIwMDUtMTItMjQgMTY6Mzk6NTgiLA0KICAgICAgICAiMjAwNS0xMC0yOCAwNzozMDowNSBQRFQiKQ0KYXMuUE9TSVhsdChkdHMpDQojIFsxXSAiMjAwNS0xMC0yMSAxODo0NzoyMiIgIjIwMDUtMTItMjQgMTY6Mzk6NTgiIA0KIyBbM10gIjIwMDUtMTAtMjggMDc6MzA6MDUiDQoNCg0KZHRzID0gYygxMTI3MDU2NTAxLDExMDQyOTU1MDIsMTEyOTIzMzYwMSwxMTEzNTQ3NTAxLA0KICAgICAgICAxMTE5ODI2ODAxLDExMzI1MTk1MDIsMTEyNTI5ODgwMSwxMTEzMjg5MjAxKQ0KbXlkYXRlcyA9IGR0cw0KY2xhc3MobXlkYXRlcykgPSBjKCdQT1NJWHQnLCdQT1NJWGN0JykNCm15ZGF0ZXMNCiMgWzFdICIyMDA1LTA5LTE4IDA4OjE1OjAxIFBEVCIgIjIwMDQtMTItMjggMjA6NDU6MDIgUFNUIg0KIyBbM10gIjIwMDUtMTAtMTMgMTM6MDA6MDEgUERUIiAiMjAwNS0wNC0xNCAyMzo0NTowMSBQRFQiDQojIFs1XSAiMjAwNS0wNi0yNiAxNjowMDowMSBQRFQiICIyMDA1LTExLTIwIDEyOjQ1OjAyIFBTVCINCiMgWzddICIyMDA1LTA4LTI5IDAwOjAwOjAxIFBEVCIgIjIwMDUtMDQtMTIgMDA6MDA6MDEgUERUIg0KDQpteWRhdGUgPSBzdHJwdGltZSgnMTYvT2N0LzIwMDU6MDc6NTE6MDAnLGZvcm1hdD0nJWQvJWIvJVk6JUg6JU06JVMnKQ0KIyBbMV0gIjIwMDUtMTAtMTYgMDc6NTE6MDAiDQoNCklTT2RhdGUoMjAwNSwxMCwyMSwxOCw0NywyMix0ej0iUERUIikNCiMgWzFdICIyMDA1LTEwLTIxIDE4OjQ3OjIyIFBEVCINCg0KdGhlZGF0ZSA9IElTT2RhdGUoMjAwNSwxMCwyMSwxOCw0NywyMix0ej0iUERUIikNCmZvcm1hdCh0aGVkYXRlLCclQSwgJUIgJWQsICVZICVIOiVNOiVTJykNCiMgWzFdICJGcmlkYXksIE9jdG9iZXIgMjEsIDIwMDUgMTg6NDc6MjIiDQoNCm15ZGF0ZSA9IGFzLlBPU0lYbHQoJzIwMDUtNC0xOSA3OjAxOjAwJykNCm5hbWVzKG15ZGF0ZSkNCiMgWzFdICJzZWMiICAgIm1pbiIgICAiaG91ciIgICJtZGF5IiAgIm1vbiIgICAieWVhciIgIA0KIyBbN10gIndkYXkiICAieWRheSIgICJpc2RzdCINCg0KbXlkYXRlJG1kYXkNCiMgWzFdIDE5DQoNCmBgYA0KDQojIyMgUE9TSVhjdCDmoLzlvI8NCuS4u+imgeeJueeCue+8muS7peenkui/m+ihjOWtmOWCqOOAgg0KYGBge3J9DQp0b2RheTwtU3lzLnRpbWUoKSAgDQp0b2RheSAgDQojIFsxXSAiMjAxNi0wNi0wNiAyMDo0MjoyMiBDU1QiICANCg0KdW5jbGFzcyhhcy5QT1NJWGN0KHRvZGF5KSkgIA0KIyBbMV0gMTQ2NTIxNjk0MiAgDQojIOino+ivu++8muavlOWmguS7iuWkqe+8jHVuY2xhc3PkuYvlkI7vvIwNCiMg5Luj6KGo5LuK5aSpMjAxNi0wNi0wNui3neemuzE5NzAtMDEtMDHkuLoxNDY1MjE2OTQy56eS44CCDQojR01U5Luj6KGo5pe25Yy677yM5b635oSP5b+X5pe26Ze077yMQ1NU5Lmf5Luj6KGo5pe25Yy6DQpgYGANCg0KIyMgOC7lpoLkvZXlnKjlvqrnjq/jgIHlh73mlbDkuK3vvIzovpPlh7rlrp7ml7bml7bpl7TmtojogJcNCmBgYHtyfQ0KdDEgPSBTeXMudGltZSgpICANCmZvciAoaSBpbiAxOjUpeyAgDQphPWErMSAgDQpiPWEqYSAgDQpwcmludChkaWZmdGltZShTeXMudGltZSgpLCB0MSwgdW5pdHMgPSAnc2VjJykpICANCn0gIA0KYGBgDQoNCiMjIDkuIEhvdyB0byBjaGFuZ2UgdGhlIGxvY2FsZSBvZiBSIGluIFJTdHVkaW8/DQoNClRoZSBSIGNvbnNvbGUgaXMgaW4gbXkgbmF0aXZlIGxhbmd1YWdlLCBob3cgY2FuIEkgc2V0IFIgdG8gRW5nbGlzaD8NCg0KMS4gR28gaW50byBSIGluc3RhbGxhdGlvbiBkaXJlY3RvcnksIGkuZS4gQzpcUHJvZ3JhbSBGaWxlc1xSXA0KDQoyLiBGcm9tIHRoZXJlIGdvIGludG8gdGhlIHN1YmZvbGRlciBldGMvDQoNCjMuIE9wZW4gd2l0aCBhIHRleHQgZWRpdG9yIChpLmUuIE5vdGVwYWQpIHRoZSBmaWxlIFJjb25zb2xlDQoNCjQuIExvb2sgaW50byB0aGUgZmlsZSBmb3IgdGhlIGxpbmUgbGFuZ3VhZ2UgPQ0KDQo1LiBSZXBsYWNlIHN1Y2ggbGluZSB3aXRoIGxhbmd1YWdlID0gZW4NCg0KNi4gU2F2ZSBhbmQgY2xvc2UgdGhlIFJjb25zb2xlIGZpbGUsIHRoZW4gcnVuIFJndWkgYWdhaW4sIGFuZCB0aGUgaW50ZXJmYWNlIHdpbGwgYmUgaW4gRW5nbGlzaA0KDQpSIHZlcnNpb24gMy4xLjMNCg0KaW5wdXQgc3RyaW5nIDEgaXMgaW52YWxpZCBpbiB0aGlzIGxvY2FsZQ0KDQpUaGUgaXNzdWUgaXMgdGhhdCB5b3UgaGF2ZSBhIEZyZW5jaC9DaGluZXNlIGV0YyBsb2NhbGUsIHdoaWNoIHVzZXMgZGlmZmVyZW50IG1vbnRoIGFuZCBkYXkgbmFtZXMgYW5kIGFiYnJldmlhdGlvbnMuIFlvdSBjYW4gY2hhbmdlIHRvIHRoZSBFbmdsaXNoIGxvY2FsZSBieSBydW5uaW5nOg0KDQpgYGB7cn0NClN5cy5zZXRsb2NhbGUoJ0xDX0FMTCcsJ2VuX0NBLnV0Zi04Jyk7DQojIG91IG1pZ2h0IGFsc28vaW5zdGVhZCBoYXZlIHRvIHJ1biB0aGlzIA0KIyAoSSd2ZSBmb3VuZCB0aGlzIHRvIGJlIG5lY2Vzc2FyeSBpbiBSU3R1ZGlvKToNClN5cy5zZXRsb2NhbGUoJ0xDX0FMTCcsJ0VuZ2xpc2gnKTsNClN5cy5zZXRsb2NhbGUoIkxDX1RJTUUiLCAiRW5nbGlzaCIpOw0KU3lzLnNldGxvY2FsZSgiTENfTUVTU0FHRVMiLCAnZW5fR0IuVVRGLTgnKQ0KDQojIE9yDQpTeXMuc2V0bG9jYWxlKCJMQ19NRVNTQUdFUyIsICdlbl9HQi5VVEYtOCcpDQpTeXMuc2V0ZW52KExBTkcgPSAiZW5fVVMuVVRGLTgiKQ0KDQpTeXMuZ2V0bG9jYWxlKCkNClN5cy5zZXRlbnYoTEFORz0nQycpDQpsb2NhbGUgPC0gU3lzLnNldGxvY2FsZShjYXRlZ29yeSA9ICJMQ19BTEwiLCBsb2NhbGUgPSAiQyIpDQoNCiMgWzFdICJMQ19DT0xMQVRFPUNoaW5lc2UgKFNpbXBsaWZpZWQpX0NoaW5hLjkzNjtMQ19DVFlQRT1DaGluZXNlIChTaW1wbGlmaWVkKV9DaGluYS45MzY7TENfTU9ORVRBUlk9Q2hpbmVzZSAoU2ltcGxpZmllZClfQ2hpbmEuOTM2O0xDX05VTUVSSUM9QztMQ19USU1FPUNoaW5lc2UgKFNpbXBsaWZpZWQpX0NoaW5hLjkzNiINCg0KYGBgDQoNCiMjIDEwLiBIb3cgdG8gdXBkYXRlIFIgaW4gUlN0dWRpbyB1c2luZyBpbnN0YWxsciBwYWNrYWdlIGZvciBXaW5kb3dzDQoNCmBgYHtyIGluc3RhbGxyIHBhY2thZ2V9DQoNCiMjIEhvdyB0byB1cGRhdGUgUiBpbiBSU3R1ZGlvIHVzaW5nIGluc3RhbGxyIHBhY2thZ2UgKGZvciBXaW5kb3dzKQ0KIyMgcGFzdGUgdGhpcyBpbnRvIHRoZSBjb25zb2xlIGFuZCBydW4gdGhlIGNvbW1hbmRzDQojIyAiVGhlIHVwZGF0ZVIoKSBjb21tYW5kIHBlcmZvcm1zIHRoZSBmb2xsb3dpbmc6IGZpbmRpbmcgdGhlIGxhdGVzdCBSIHZlcnNpb24sIGRvd25sb2FkaW5nIGl0LCBydW5uaW5nIHRoZSBpbnN0YWxsZXIsIGRlbGV0aW5nIHRoZSBpbnN0YWxsYXRpb24gZmlsZSwgY29weSBhbmQgdXBkYXRpbmcgb2xkIHBhY2thZ2VzIHRvIHRoZSBuZXcgUiBpbnN0YWxsYXRpb24uIg0KIyMgbW9yZSBpbmZvIGhlcmU6IGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9pbnN0YWxsci9pbmRleC5odG1sDQoNCiMgVGhlIGluc3RhbGxyIHBhY2thZ2Ugc2VlbXMgbGlrZSBhIGdyZWF0IHNvbHV0aW9uIGJ1dCB1bmZvcnR1bmF0ZWx5IGlzIG9ubHkgZm9yIFdpbmRvd3MuDQoNCiMgaW5zdGFsbGluZy9sb2FkaW5nIHRoZSBwYWNrYWdl77yMbG9hZCAvaW5zdGFsbCtsb2FkIGluc3RhbGxyICANCmlmKCFyZXF1aXJlKGluc3RhbGxyKSl7IA0KICBpbnN0YWxsLnBhY2thZ2VzKCJpbnN0YWxsciIpOyANCiAgcmVxdWlyZShpbnN0YWxscil9IA0KDQojIHVzaW5nIHRoZSBpbnN0YWxsciBwYWNrYWdlLCBpbnN0YWxsLCBtb3ZlLCB1cGRhdGUucGFja2FnZSwgcXVpdCBSLg0KIyMgV2F0Y2ggZm9yIHNtYWxsIHBvcCB1cCB3aW5kb3dzLiBUaGVyZSB3aWxsIGJlIG1hbnkgcXVlc3Rpb25zIGFuZCB0aGV5IGRvbid0IGFsd2F5cyBwb3AgdG8gdGhlIGZyb250LiANCiMjIE5vdGU6IEl0IHdhcm5zIHRoYXQgaXQgbWlnaHQgd29yayBiZXR0ZXIgaW4gUmd1aSBidXQgSSBkaWQgaXQgaW4gUnN0dWRpbyBhbmQgaXQgd29ya2VkIGp1c3QgZmluZS4gDQojIHRoaXMgd2lsbCBzdGFydCB0aGUgdXBkYXRpbmcgcHJvY2VzcyBvZiB5b3VyIFIgaW5zdGFsbGF0aW9uLiAgDQojIEl0IHdpbGwgY2hlY2sgZm9yIG5ld2VyIHZlcnNpb25zLCBhbmQgaWYgb25lIGlzIGF2YWlsYWJsZSwgd2lsbCBndWlkZSB5b3UgdGhyb3VnaCB0aGUgZGVjaXNpb25zIHlvdSdkIG5lZWQgdG8gbWFrZS4NCnVwZGF0ZVIoKQ0KDQpgYGANCg0KIyMgMTEuIFIgc2Vzc2lvbkluZm8sIHZlcnNpb24sIHBhY2thZ2VTdGF0dXMNCg0KYGBge3J9DQojIHNlc3Npb24sIHZlcnNpb24sIHBhY2thZ2VTdGF0dXMNCnNlc3Npb25JbmZvKCkNCnZlcnNpb24NCg0KIyBnZXQgciB2ZXJzaW9uDQpSLnZlcnNpb24uc3RyaW5nDQoNCnBhY2thZ2VTdGF0dXMoKQ0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K